const Ajv = require("ajv");
const localize = require("ajv-i18n");
const ajv = new Ajv({
  // format_1. 自定义format（格式化）
  formats: { myEmail: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/ },
  strict: false,
  allErrors: true,
});

const ajvError = require("ajv-errors");
ajvError(ajv);

// format_2. 自定义format
ajv.addFormat("myEmail2", {
  validate: data => {
    // console.log("data ->", data);
    const reg = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
    return reg.test(data);
  },
});

// schema 初步测试
// const schema = {
//   type: "string",
//   minLength: 10,
// };

// keyword_1. 自定义keyword（validate函数方式）
// ajv.addKeyword({
//   keyword: "isPass",
//   validate: function (schemaValue, dataValue) {
//     console.log(schemaValue, dataValue);
//     if (schemaValue) return true;
//     else return dataValue.length >= 10;
//   },
// });

// keyword_2. 自定义keyword（compile方式）
// ajv.addKeyword({
//   keyword: "isPass",
//   compile: function (schemaValue, parentSchemaValue) {
//     console.log(schemaValue, parentSchemaValue);
//     // compile 需要返回一个函数，在返回的这个函数里面进行验证
//     // return true;
//     // 可以拿到父级schema的值，以实现更加复杂的验证
//     return () => (schemaValue ? true : parentSchemaValue.minLength === 10);
//   },
//   // 元schema：定义schemaValue的schema（在验证前会先验证元schema是否符合规则）
//   metaSchema: {
//     type: "boolean",
//   },
// });

// keyword_3. 自定义keyword（macro方式）
ajv.addKeyword({
  keyword: "isPass",
  // macor：参数与compile一样，但macor返回的不是一个函数，而是一个schema
  macro: function (schemaValue, parentSchemaValue) {
    console.log(schemaValue, parentSchemaValue);
    // 返回的这个schema会被合并到isPass这个关键字同级的位置
    return {
      maxLength: 16,
    };
  },
});

const schema = {
  type: "object",
  properties: {
    name: {
      type: "string",
      minLength: 10,
      // isPass: false, // 使用自定义的schema "isPass"  注意：errorMessage不支持自定义关键字，且与ajv-i18n冲突
      errorMessage: {
        type: "名称必须是字符串",
        minLength: "名称长度至少为10个字符",
      },
    },
    age: {
      type: "number",
      minimum: 18,
    },
    hobbies: {
      type: "array",
      items: [
        // 定义元组结构
        {
          type: "string",
        },
        {
          type: "number",
        },
      ],
      additionalItems: false, // 不允许额外元素
    },
    email: {
      type: "string",
      // format: "myEmail",
      format: "myEmail2",
      errorMessage: {
        type: "邮箱必须是字符串",
        format: "请输入有效的邮箱地址（如 user@example.com）",
      },
    },
  },
  required: ["name", "age", "hobbies"], // 明确必填字段
};

const validate = ajv.compile(schema);
// const data = "hello123456";
const data = {
  name: "tom123456",
  age: 18,
  hobbies: ["eat", 12],
  email: "12345@qq.com123",
};
const valid = validate(data);

if (!valid) {
  // localize.zh(validate.errors);
  console.log(validate.errors);
} else {
  console.log("数据有效！");
}
